﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security;
using System.Threading;
namespace Lxzhu.OpenGL
{
    /// <summary>
    /// 所有标准的Gl函数都定义在这里.
    /// </summary>   
    public partial class Gl
    {

        private static List<String> sExtList = null;        
        private static object sLocker = new Object();        
        #region 特性查询
        [DllImport(GlDll, CallingConvention = GlCalling,EntryPoint="glGetString"), SuppressUnmanagedCodeSecurity]
        internal static extern IntPtr glGetString0(int name);
        public static  string glGetString(int name)
        {
            String ret = String.Empty;
            IntPtr ptr = glGetString0(name);
            if (IntPtr.Zero != ptr)
                ret = Marshal.PtrToStringAnsi(ptr);
            return ret;
        }
        public static String glGetString(VersionComponent ver)
        {
            return glGetString((int)ver);
        }
        private static void loadExtension(){
            Monitor.Enter(sLocker);
            try
            {
                if (sExtList == null)
                {
                    String str = glGetString(VersionComponent.GL_EXTENSIONS);
                    String[] extNames = str.Split(" ".ToCharArray());
                    sExtList = extNames.ToList();
                }
            }
            catch (Exception ex) { }
            finally
            {
                Monitor.Exit(sLocker);
            }
        }
        public static List<String> getExtensions()
        {
            loadExtension();
            return sExtList.ToList();
        }
        public static bool isSupported(string ext)
        {
            loadExtension();
            return sExtList.Contains(ext);
        }
        #endregion
        #region 辅助功能
        [DllImport(GlDll,CallingConvention=GlCalling),SuppressUnmanagedCodeSecurity]
        public static extern void glFlush();
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glFinish();
        #endregion
        #region 开始和结束绘制
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glBegin(PrimitiveType pt);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glEnd();
        #endregion        
        #region 操作矩阵
        [DllImport(GlDll, CallingConvention = GlCalling)]
        public static extern void glViewport(int xmin, int ymin, int xmax, int ymax);
        [DllImport(GlDll, CallingConvention = GlCalling)]
        public static extern void glMatrixMode([MarshalAs(UnmanagedType.U4)]MatrixMode mode);
        [DllImport(GlDll, CallingConvention = GlCalling),SuppressUnmanagedCodeSecurity]
        public static extern void glLoadIdentity();
        /// <summary>
        /// 
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <param name="bottom"></param>
        /// <param name="top"></param>
        /// <param name="near"></param>
        /// <param name="far"></param>
        [DllImport(GlDll,CallingConvention=GlCalling),SuppressUnmanagedCodeSecurity]
        public static extern void glOrtho(double left, double right, double bottom, double top, double near, double far); 
        //public static extern void glPopMatrix();
        //public static extern void glPushMatrix();
        #endregion
        #region 旋转平移
        [DllImport(GlDll,CallingConvention=GlCalling,EntryPoint="glScalef"),SuppressUnmanagedCodeSecurity]
        public static extern void glScale(float x, float y, float z);
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glScaled"), SuppressUnmanagedCodeSecurity]
        public static extern void glScale(double x, double y, double z);
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glTranslatef"), SuppressUnmanagedCodeSecurity]
        public static extern void glTranslate(float x, float y, float z);
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glTranslated"), SuppressUnmanagedCodeSecurity]
        public static extern void glTranslate(double x, double y, double z);
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glRotatef"), SuppressUnmanagedCodeSecurity]
        public static extern void glRotate(float angle, float x, float y, float z);
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glRotated"), SuppressUnmanagedCodeSecurity]
        public static extern void glRotate(double angle, double x, double y, double z);
        #endregion
        #region 颜色处理
        [DllImport(GlDll,CallingConvention=GlCalling),SuppressUnmanagedCodeSecurity]
        public static extern void glClearColor(float red, float green, float blue,float alpha);
        [DllImport(GlDll,CallingConvention=GlCalling,EntryPoint="glColor3f"),SuppressUnmanagedCodeSecurity]
        public static extern void glColor(float red, float green, float blue);
        [DllImport(GlDll,CallingConvention=GlCalling ),SuppressUnmanagedCodeSecurity]
        public static extern void glClear([MarshalAs(UnmanagedType.U4)]BufferBit buffer);
        #endregion
        #region 几何体属性
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glPointSize(float size);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glLineWidth(float size);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glLineStipple(int factor, int pattern);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glLineStipple(int factor, LineStyle pattern);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glPolygonMode(Face face, PolygonMode mode);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glFrontFace(Direction dir);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glCullFace(Face face);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glPolygonStipple(byte[] pattern);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glEdgeFlag(bool flag);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glEdgeFlagv(bool[] flags);
        #endregion
        #region glRect
        [DllImport(GlDll, CallingConvention = GlCalling,EntryPoint="glRects"), SuppressUnmanagedCodeSecurity]
        public static extern void glRect(short x1, short y1, short x2, short y2);
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glRecti"), SuppressUnmanagedCodeSecurity]
        public static extern void glRect(int x1, int y1, int x2, int y2);
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glRectf"), SuppressUnmanagedCodeSecurity]
        public static extern void glRect(float x1, float y1, float x2, float y2);
        [DllImport(GlDll, CallingConvention = GlCalling,EntryPoint="glRectd"), SuppressUnmanagedCodeSecurity]
        public static extern void glRect(double x1, double y1, double x2, double y2);
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glRectsv"), SuppressUnmanagedCodeSecurity]
        public static extern void glRectv(short[] first, short[] second);
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glRectiv"), SuppressUnmanagedCodeSecurity]
        public static extern void glRectv(int[] first, int[] second);
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glRectfv"), SuppressUnmanagedCodeSecurity]
        public static extern void glRectv(float[] first, float[] second);
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glRectdv"), SuppressUnmanagedCodeSecurity]
        public static extern void glRectv(double[] first, double[] second);
        #endregion
        #region glNormal
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glNormal3b"), SuppressUnmanagedCodeSecurity]
        public static extern void glNormal(byte nx, byte ny, byte nz);
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glNormal3s"), SuppressUnmanagedCodeSecurity]
        public static extern void glNormal(short nx, short ny, short nz);
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glNormal3i"), SuppressUnmanagedCodeSecurity]
        public static extern void glNormal(int nx, int ny, int nz);
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glNormal3f"), SuppressUnmanagedCodeSecurity]
        public static extern void glNormal(float nx, float ny, float nz);
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glNormal3d"), SuppressUnmanagedCodeSecurity]
        public static extern void glNormal(double nx, double ny, double nz);

        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glNormal3bv"), SuppressUnmanagedCodeSecurity]
        public static extern void glNormalv(byte[] nv);
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glNormal3sv"), SuppressUnmanagedCodeSecurity]
        public static extern void glNormalv(short[] nv);
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glNormal3iv"), SuppressUnmanagedCodeSecurity]
        public static extern void glNormalv(int[] nv);
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glNormal3fv"), SuppressUnmanagedCodeSecurity]
        public static extern void glNormalv(float[] nv);
        [DllImport(GlDll, CallingConvention = GlCalling, EntryPoint = "glNormal3dv"), SuppressUnmanagedCodeSecurity]
        public static extern void glNormalv(double[] nv);
        #endregion
        #region glEnable
        [DllImport(GlDll,CallingConvention=GlCalling),SuppressUnmanagedCodeSecurity]
        public static extern void glEnable(Capability cap);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glEnable(int cap);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glDisable(Capability cap);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glDisable(int cap);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern bool glIsEnabled(Capability cap);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern bool glIsEnabled(int cap);
        #endregion
        #region glGet
        [DllImport(GlDll,CallingConvention=GlCalling),SuppressUnmanagedCodeSecurity]
        public static extern void glGetIntegerv(int pname, [Out] Int32[] @params);
        [DllImport(GlDll,CallingConvention=GlCalling ),SuppressUnmanagedCodeSecurity]
        public static extern void glGetFloatv(int pname, [Out] float[] @params);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glGetDoublev(int pname, [Out] double[] @params);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glGetBooleanv(int pname, [Out] bool[] @params);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glGetPointv(int pname, [Out] IntPtr @params);

        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glGetIntegerv(ConfigurationOrState pname, [Out] Int32[] @params);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glGetFloatv(ConfigurationOrState pname, [Out] float[] @params);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glGetDoublev(ConfigurationOrState pname, [Out] double[] @params);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glGetBooleanv(ConfigurationOrState pname, [Out] bool[] @params);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        public static extern void glGetPointv(ConfigurationOrState pname, [Out] IntPtr @params);
        [DllImport(GlDll, CallingConvention = GlCalling), SuppressUnmanagedCodeSecurity]
        [return:MarshalAs(UnmanagedType.U4)]
        public static extern ErrorCode glGetError();

        #endregion
    }

}
